package com.copro.chemdb.stat.rule;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.ihelpuoo.db.sql.SQLSegment;
import org.ihelpuoo.util.Properties;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;

import com.copro.chemdb.constants.ConstValue;
import com.copro.chemdb.constants.ConstValueUtils;
import com.copro.chemdb.stat.AbstractStatRule;
import com.copro.chemdb.stat.StatResult;
import com.copro.chemdb.subject.Subject;
import com.copro.chemdb.subject.opt.Option;
import com.copro.simple.Application;
import com.copro.simple.SimpleException;
import com.copro.simple.db.FreeCallback;
import com.copro.simple.db.SQLSet;

public class Rule1 extends AbstractStatRule {

	static class FreeGetter implements FreeCallback {

		private List<StatOption> list;
		private Subject subject;
		private int type;

		public FreeGetter(Subject subject, int type) {
			this.list = new ArrayList<StatOption>();
			this.subject = subject;
			this.type = type;
		}

		public List<StatOption> getList() {
			return this.list;
		}

		@Override
		public void exec(Connection conn, SQLSet sqls) throws SQLException {
			Application app = (Application) sqls;
			Statement stm = conn.createStatement(
					ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_UPDATABLE);
			SQLSegment sql = null;
			sql = app.getSQL("rule1CountAnswer");
			sql.set("subjectId", subject.getId());
			sql.set("type", type);
			ResultSet rs = stm.executeQuery(sql.toString());
			List<Option> options = subject.getOptions();
			int index = 0, id, count;
			Option option;
			StatOption statOption;
			while (rs.next()) {
				id = rs.getInt(1);
				count = rs.getInt(2);
				for (; index < options.size(); index++) {
					option = options.get(index);
					statOption = new StatOption(option);
					if (id == option.getId()) {
						statOption.setCount(count);
					}
					if (id >= option.getId()) {
						this.list.add(statOption);
					} else {
						// index--;
						break;
					}
				}
			}
			for (; index < options.size(); index++) {
				option = options.get(index);
				statOption = new StatOption(option);
				this.list.add(statOption);
			}

		}
	}

	@Override
	public StatResult doStat(Application app, Subject subject, int type)
			throws SimpleException {
		StatResult statResult = new StatResult();
		SQLSegment sql = app.getSQL("rule1CountResult");
		sql.set("subjectId", subject.getId());
		sql.set("type", type);
		int count = app.getCount(sql.toString());
		if (subject.isEnum()) {
			List<ConstValue> values = ConstValueUtils.getConstValueList(app,
					subject.getEnumType());
			List<Option> options = new ArrayList<Option>();
			Option option = null;
			ConstValue value = null;
			for (int i = 0; i < values.size(); i++) {
				value = values.get(i);
				option = new Option();
				option.setId(value.getId());
				option.setText(value.getName());
				options.add(option);
			}
			subject.setOptions(options);
		}
		FreeGetter fg = new FreeGetter(subject, type);
		app.exec(fg);
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("count", new Integer(count));
		result.put("statOptionSet", fg.getList());
		result.put("text", subject.getBrief());
		result.put("subject", subject);
		statResult.setResult(result);
		statResult.setForwardName("rule1");

		// start to create chart
		List<StatOption> optionSet = fg.getList();
		if (Subject.SINGLE_SELECT == subject.getType()) {
			DefaultPieDataset dataset = new DefaultPieDataset();
			if (count > 0) {
				for (int si = 0; si < optionSet.size(); si++) {
					StatOption sOption = optionSet.get(si);
					dataset.setValue(sOption.getOption().getText(), sOption
							.getCount());
				}
			}
			app.createPieStatChart(subject.getId(), dataset);
		} else {
			DefaultCategoryDataset dataset = new DefaultCategoryDataset();
			if (count > 0) {
				for (int si = 0; si < optionSet.size(); si++) {
					StatOption sOption = optionSet.get(si);
					dataset.setValue(sOption.getCount(), sOption.getOption()
							.getText(), "");
				}
			}
			app.createBarStatChart(subject.getId(), dataset);
		}

		return statResult;
	}

	@Override
	public void setup(Properties conf) {

	}

}
